package com.cctc.juc.demo.Bitc.BwaitAndnotify.Bsynchronized;

/**
 * 银行账户：实现 [线程安全] 转账操作。
 */
public class Account {
    // 账户余额
    private int balance;
    // 共享资源
    private Resource resource;

    public Account(int balance) {
        this.balance = balance;
        this.resource = ResourceHolder.getInstance();
    }

    /**
     * 转账。
     *
     * @param target 目标账户。
     * @param money  转账金额。
     */
    public void transfer(Account target, int money) {
        // 同时申请转入账户和转出账户，作为共享资源，直到全部申请成功后再继续向下执行。
        resource.apply(this, target);
        try {
            // 对申请到的转出账户进行加锁，保证转出的原子操作。
            synchronized (this) {
                // 对申请到的转入账户进行加锁，保证转入的原子操作。
                synchronized (target) {
                    if (this.balance >= money) {
                        this.balance -= money;
                        target.balance += money;
                    }
                }
            }
        } finally {
            // 执行结束后，释放共享资源。
            resource.release(this, target);
        }
    }

}
